﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UFIDA.U9.InvDoc.Enums;
using UFIDA.U9.InvDoc.MiscRcv;
using UFSoft.UBF.Business;
using UFSoft.UBF.Eventing;

namespace UFIDA.U9.CusDev.AITPlugInBE
{
    /// <summary>
    /// 调用AIT探针,触发AIT Flow
    /// BE插件
    /// </summary>
    internal class CallForAIT : IEventSubscriber
    {
        public void Notify(params object[] args)
        {
            if (args == null || args.Length == 0 || !(args[0] is EntityEvent)) return;
            BusinessEntity.EntityKey key = ((EntityEvent)args[0]).EntityKey;

            if (key == null || key.GetEntity() == null) return;
            BusinessEntity entity = key.GetEntity();
            if (entity == null) return;
            //获取AIT配置
            JObject config = FileUtils.GetAITConfig();
            if (config == null) return;
            try
            {
                //通过配置文件判断是否需要调用探针服务
                JObject config1 = this.getEnittyConfig(entity);
                if (config1!=null)
                {
                    //调用探针服务
                    this.CallAIT(entity, config1);
                }
            }catch (Exception ex)
            {
                throw new Exception($"AIT错误消息:{ex.Message}", ex);
            }

        }

        /// <summary>
        /// 判断是否调用AIT探针
        /// 检查配置文件中是否存在该实体的配置
        /// </summary>
        /// <param name="entity"></param>
        /// <returns>匹配后的配置项</returns>
        private JObject getEnittyConfig(BusinessEntity entity)
        {
            //获取配置信息
            JObject config = FileUtils.GetAITConfig();
            if (config == null) return null;

            var config1 = (JArray)config["entity"][entity.GetType().FullName];
            if (config1 == null||config1.Count==0)
                return null;

            //上下文设置
            var dict = new Dictionary<string, object>();
            //当前数据设置
            foreach (var item in entity.Values.Keys)
            {
                string key = item.ToString();
                if (key.Contains("."))
                {
                    //更新扩展字段名字
                    key = key.Replace(".", "_");
                }
                dict[key] = entity.Values[item.ToString()];
            }
            //原数据设置,实体新增状态没有原始数据,可以在公式中==null
            foreach (var item in entity.OriginalData.Values.Keys)
            {
                string key = "OriginalData_" + item.ToString();
                if (key.Contains("."))
                {
                    //更新扩展字段名字
                    key = key.Replace(".", "_");
                }
                dict[key] = entity.OriginalData.Values[item.ToString()];
            }
            //逐行匹配when条件
            foreach (var item in config1)
            {
                //对when进行动态解析
                String when = item["when"].ToString();
                if (String.IsNullOrEmpty(when))
                    return (JObject)item;

                //lambda动态解析
                //需要dll NReco.LambdaParser.dll
                var lambdaParser = new NReco.Linq.LambdaParser();
                var ret = (bool)lambdaParser.Eval(when, dict);
                if (ret) return (JObject)item;
            }

            return null;
        }

        /// <summary>
        /// 通用调用AIT探针
        /// </summary>
        /// <param name="entity">传入实体</param>
		public void CallAIT(BusinessEntity entity, JObject config1)
        {
            //获取AIT配置
            if (config1 == null)
                return;
            JObject config = FileUtils.GetAITConfig();
            string url = config["url"].ToString();
            bool async = config1.Value<bool>("async");
            object probeName = config1["probeName"];
            if (probeName == null) return;

            //远程调用,并记录日志
            Dictionary<string, object> parms = new Dictionary<string, object>();
            parms.Add("type", probeName.ToString());
            parms.Add("args", EntityUtils.getCode(entity));
            parms.Add("async", async);
            string retstr = ufida.u9.ait.openapi.utils.HttpUtils.Get(url, parms);
            //返回值判断
            JObject ret = (JObject)JsonConvert.DeserializeObject(retstr);
            int code = ret.Value<int>("code");
            string msg = ret.Value<string>("msg");
            if (code != 200)
                throw new Exception(msg);
        }
    }
}
